#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
#include <pthread.h>
#include <stdlib.h>
#include <signal.h>


int server_running = 1;

void sigint_handler(int sig) 
{
    printf("\nShutting down server...\n");
    server_running = 0;
}

void* handle_client(void* args) 
{
    int clientfd = *(int*)args;

    pthread_detach(pthread_self());

    char buffer[128] = {0};

    while (1) {
        int cnt = recv(clientfd, buffer, 128, 0);
        if (0 == cnt) {
            break;
        }

        buffer[cnt] = 0;
        printf("clientfd:%d, msg: %s\n", clientfd, buffer);
    }

    close(clientfd);
    return NULL;
}

int main() 
{

    // 注册信号 
    // signal(SIGINT, sigint_handler);


    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Socket creation error");
        return -1;
    }

    int opt = 1;
    int n = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    if (n < 0) {
        perror("setsockopt error");
        close(sockfd);
        return -2;
    }

    // struct sockaddr_in addr; // <netinet/in.h>
    // addr.sin_family = AF_INET;
    // // addr.sin_addr.s_addr = INADDR_ANY;
    // // addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // addr.sin_port = htons(0);

    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(8080);

    n = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    if (n < 0) {
        perror("bind error");
        close(sockfd);
        return -3;
    }

    n = listen(sockfd, 8);
    if (n < 0) {
        perror("listen error");
        close(sockfd);
        return -4;
    }

    
    while (server_running) {

        struct sockaddr_in clientAddr;
        bzero(&clientAddr, sizeof(clientAddr));
        socklen_t len = sizeof(clientAddr);

        int clientfd = accept(sockfd, (struct sockaddr*)&clientAddr, &len);
        if (clientfd < 0) {
            perror("accept error");
            return -4;
        }

        int* fd = (int*)malloc(sizeof(int));
        *fd = clientfd;

        pthread_t thread;
        pthread_create(&thread, NULL, handle_client, fd);
    }

    close(sockfd);

    return 0;
}